package com.styytech.dadabao.api.response;

import android.util.Log;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.MySSLSocketFactory;
import com.loopj.android.http.RequestParams;
import com.styytech.dadabao.api.requestresult.RequestResult;
import com.styytech.dadabao.constant.ConstantsServerUrl;
import com.styytech.dadabao.exception.ArgumentsException;
import com.styytech.dadabao.exception.RequestException;
import com.styytech.dadabao.log.LogUtil;

import org.apache.http.Header;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;

/**
 * 接口请求类
 *
 * @description
 */
public class ClientRequestUtil {

    /**
     * 基础URL
     */
    public static String baseUrl = ConstantsServerUrl.server;

    /**
     * 请求超时时间
     */
//    public static Integer timeOut;

    /**
     * 用户代理，指浏览器
     */
    public static String userAgent;

    public static String keyStorPath;

    /**
     * 是否使用SSL请求，根据基础URL判断
     */
    public static boolean useSSL;

    /**
     * 请求完之后结果对象
     */
    protected RequestResult result;

    private AbstractResponseResult httpResponseResult;

    /**
     * 构造函数
     *
     * @param result
     */
    public ClientRequestUtil(RequestResult result) {
        this.result = result;
        this.httpResponseResult = result.getHttpResponseResult();
    }

    /**
     * POST请求
     *
     * @param businessUrl 业务URL
     * @param params      业务参数
     * @throws Exception
     * @throws ArgumentsException
     * @throws RequestException
     * @version
     */
    public void doPost(final String businessUrl, RequestParams params) throws RequestException, ArgumentsException {
        checkBusinessUrl(businessUrl);
        AsyncHttpClient client = getHttpClient();
        Log.e("fasfas", "getFullUrl(businessUrl)---" + getFullUrl(businessUrl));
        client.post(getFullUrl(businessUrl), params, getHandle(businessUrl));
    }

    /**
     * GET请求
     *
     * @param businessUrl 业务URL
     * @return 请求结果
     * @throws Exception
     * @throws ArgumentsException
     * @throws RequestException
     * @version
     */
    public void doGet(String businessUrl) throws RequestException, ArgumentsException {
        checkBusinessUrl(businessUrl);
        AsyncHttpClient client = getHttpClient();
        client.get(getFullUrl(businessUrl), getHandle(businessUrl));
    }


    /**
     * 结合业务URL，获取请求的完整URL
     *
     * @param businessUrl 业务部分URL,不需要以/开头
     * @return
     * @version
     */
    protected static String getFullUrl(String businessUrl) {
        return baseUrl + "/" + businessUrl;
    }

    /**
     * 获取Handle
     *
     * @param businessUrl 业务部分URL
     * @return 请求完成后的Handle
     * @version
     */
    protected AsyncHttpResponseHandler getHandle(final String businessUrl) {
        AsyncHttpResponseHandler handle = new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
                super.onSuccess(statusCode, headers, response);
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                super.onSuccess(statusCode, headers, response);
                try {
                    parseSuccessResult(response);
                    result.setUrl(getFullUrl(businessUrl));
                    result.doBusiness();
                } catch (JSONException e) {
                    e.printStackTrace();
                    httpResponseResult.executeError("数据异常",
                            AbstractResponseResult.RESPONSE_DATA_FORMAT_ERROR);
                }
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, String responseString) {
                super.onSuccess(statusCode, headers, responseString);
                httpResponseResult.executeError("数据异常",
                        AbstractResponseResult.RESPONSE_DATA_FORMAT_ERROR);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
                super.onFailure(statusCode, headers, throwable, errorResponse);
                /*** 服务器或网络错误 */
                httpResponseResult.HttpError("连接服务器失败", -1);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {
                super.onFailure(statusCode, headers, throwable, errorResponse);
                /*** 服务器或网络错误 */
                httpResponseResult.HttpError("连接服务器失败", -1);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                super.onFailure(statusCode, headers, responseString, throwable);
                /*** 服务器或网络错误 */
                httpResponseResult.HttpError("连接服务器失败", -1);
            }
        };
        return handle;
    }

    /**
     * 解析请求成功数据
     *
     * @param response
     * @throws JSONException
     * @version
     */
    protected void parseSuccessResult(JSONObject response) throws JSONException {
        LogUtil.i("123", response + "");
        if (response != null) {
            result.setResponseData(response.has("responseData") ? response.getJSONArray("responseData") : null);
            result.setSuccess(response.has("success") ? response.getBoolean("success") : false);
            result.setMessage(response.has("message") ? response.getString("message") : null);
            parseResponse(result.getResponseData());
        }
    }

    /**
     * 解析responseData数据
     *
     * @param response
     * @throws JSONException
     * @version
     */
    protected void parseResponse(Object response) throws JSONException {
        if (response != null) {
            JSONArray jsonArray = (JSONArray) response;
            JSONObject jsonObject = null;
            if (!jsonArray.isNull(0)) {
                jsonObject = jsonArray.getJSONObject(0);
            }
            if (jsonObject != null) {
                result.setRows(jsonObject.has("rows") ? jsonObject.getJSONArray("rows") : null);
                result.setPage(jsonObject.has("page") ? jsonObject.getInt("page") : 1);
                result.setPageSize(jsonObject.has("pageSize") ? jsonObject.getInt("pageSize") : 1);
                result.setPages(jsonObject.has("pages") ? jsonObject.getInt("pages") : 1);
                result.setTotal(jsonObject.has("total") ? jsonObject.getInt("total") : 1);
            }

        }
    }

    /**
     * 获取SSLSocketFactory 对象
     *
     * @return SSLSocketFactory 对象
     * @throws Exception
     * @throws RequestException
     * @version
     */
    protected static SSLSocketFactory newSSLSocketFactory() throws RequestException {

        KeyStore trustStore = null;
        SSLSocketFactory sf = null;
        try {
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);
            sf = new MySSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        } catch (Exception e) {
            e.printStackTrace();
        }

//        if (!new File(keyStorPath).exists()) {
//            return null;
//        }
//        FileInputStream fin = null;
//        SSLSocketFactory sf = null;
//        try {
////            fin = new FileInputStream(keyStorPath);
//            KeyStore trusted = KeyStore.getInstance("BKS");
////            trusted.load(fin, "mysecret".toCharArray());
//            sf = new SSLSocketFactory(trusted);
//            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
//        } catch (Exception e) {
//            throw new RequestException(e.getMessage());
//        } finally {
//            if (fin != null) {
//                try {
//                    fin.close();
//                } catch (IOException e) {
//                    throw new RequestException(e.getMessage());
//                }
//            }
//        }

        return sf;
    }

    /**
     * 获取AsyncHttpClient实例
     *
     * @return AsyncHttpClient实例
     * @throws Exception
     * @throws RequestException
     * @throws ArgumentsException
     * @version
     */
    protected AsyncHttpClient getHttpClient() throws RequestException, ArgumentsException {
        init();
        AsyncHttpClient client = new AsyncHttpClient();
        //TODO 设置ssl证书
//        client.setUserAgent(userAgent);
        if (useSSL) {
            client.setSSLSocketFactory(newSSLSocketFactory());
        }
//        client.setTimeout(timeOut);
//        client.setMaxRetriesAndTimeout(3,timeOut);
        return client;
    }

    /**
     * 检查业务URL部分是否有效(判断是否为Null或者"")
     *
     * @param businessUrl 业务URL
     * @throws ArgumentsException
     * @version
     */
    protected void checkBusinessUrl(String businessUrl) throws ArgumentsException {
        if (businessUrl == null || "".equals(businessUrl)) {
            throw new ArgumentsException("String businessUrl is null or empty");
        }
    }

    /**
     * 数据初始化
     *
     * @throws ArgumentsException
     * @version
     */
    protected void init() throws ArgumentsException {
        if (this.result == null) {
            throw new ArgumentsException("RequestResult result is null");
        }

        if (baseUrl == null || "".equals(baseUrl)) {
            throw new ArgumentsException("String baseUrl is null or empty");
        }

//        timeOut = timeOut == null || timeOut.intValue() == 0 ? 10000 : timeOut;
        userAgent = userAgent == null || "".equals(userAgent) ? "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36"
                : userAgent;

//        keyStorPath = CommonString.keyStoreDirectory() + CommonString.myKeystoreName;
        //TODO 设置证书地址

        useSSL = baseUrl.startsWith("https");
    }

}
